#!/usr/bin/env bash

set -e

# CLI handling.
arch=x86_64
debug=false
debug_qemu=''
kgdb=false
nographic=false
extra_append=''
extra_flags=''
while getopts a:dkn OPT; do
  case "$OPT" in
    a)
      arch=$OPTARG
      ;;
    d)
      debug=true
      extra_flags="$extra_flags -S -s"
      ;;
    k)
      debug=true
      extra_append="$extra_append kgdbwait"
      # For those who want to try KDB.
      #extra_append="$extra_append kgdbwait kgdboc=kbd"
      extra_flags="$extra_flags -serial tcp::1234,server,nowait"
      kgdb=true
      ;;
    n)
      extra_append="$extra_append console=ttyS0"
      extra_flags="$extra_flags -nographic"
      nographic=true
      ;;
    q)
      debug_qemu='gdb -q -ex start --args'
      ;;
  esac
done
shift "$(($OPTIND - 1))"
extra_flags="$extra_flags $@"

images_dir='buildroot/output/images'
case "$arch" in
  x86_64)
      if $kgdb; then
        extra_append="$extra_append kgdboc=ttyS0,115200"
      fi
      cmd="$debug_qemu ./buildroot/output/host/usr/bin/qemu-system-x86_64 \
        -M pc \
        -append 'root=/dev/vda $extra_append' \
        -drive file=${images_dir}/rootfs.ext2,if=virtio,format=raw \
        -kernel ${images_dir}/bzImage \
        -m 128M \
        -net nic,model=virtio \
        -net user \
        -smp 1 \
        $extra_flags
      "
    ;;
  arm)
    if $kgdb; then
      extra_append="$extra_append kgdboc=ttyAMA0,115200"
    fi
    cmd="qemu-system-arm \
      -M versatilepb \
      -append 'root=/dev/sda $extra_append' \
      -drive file=${images_dir}/rootfs.ext2,if=scsi,format=raw \
      -dtb ${images_dir}/versatile-pb.dtb \
      -kernel ${images_dir}/zImage \
      -m 128M \
      -net nic,model=rtl8139 \
      -net user \
      -serial stdio \
      -smp 1 \
      $extra_flags"
    ;;
esac
if "$debug" && ! "$nographic" && [ ! "$arch" = 'arm'  ]; then
  eval "$cmd" &>/dev/null &
  # TODO: Ctrl +C gets sent to QEMU? Why? Does not happen if I run
  # ./rungdb manually from outside this script!!! But why?!?!
  # eval has nothing to do with it, minimized example with explicit
  # commands also fails in the same way...
  #./rungdb
else
  eval "$cmd"
fi
